<template>
  <div>
    <el-page-header @back='goBack' />
    <el-card v-if='blogData' class='box-card' style='margin-top: 20px;'>
      <div slot='header' class='clearfix'>
        <el-row :gutter='10'>
          <el-col :span='1'>
            <el-avatar style='width: 60px; height: 60px;' :src='blogData.author.avatar' />
          </el-col>
          <el-col :span='6'>
            <strong>作者： {{ blogData.author.userName }}</strong>
            <strong class='admin' v-if='blogData.author.isAdmin'>管理员</strong>
            <br />
            <span style='color: #8c939d;'>发布时间： {{ blogData.lastModified | timeFormat }}</span>
          </el-col>
          <el-col :span='10' :offset='7' style='display: flex;justify-content: end;'>
            <el-button v-if='blogData.approved' type='warning' circle @click='switchLike'>
              <span class='iconfont' :class="isLike?'good-fill':'good'" />
            </el-button>
            <el-button v-if='!isSelf' type='danger' @click='switchAttention'>
              <span class='iconfont' :class="isAttention?'close':'add'"> {{ isAttention ? '取关' : '关注' }}</span>
            </el-button>
            <el-button v-if='!isSelf' type='danger' @click='switchBlack'>
              <span class='iconfont' :class="isBlack?'close':'laHei'"> {{ isBlack ? '取消拉黑' : '拉黑' }}</span>
            </el-button>
            <el-button v-if='!isSelf' type='danger' @click='showDialog'>
              <span class='iconfont juBao'> 举报文章</span>
            </el-button>
            <el-button icon='el-icon-delete' v-if='isSelf || userData?.isAdmin' type='danger' @click='deleteBlog'>
              <span class='iconfont'> 删除文章</span>
            </el-button>
          </el-col>
        </el-row>
      </div>
      <el-row :gutter='10'>
        <el-col :span='24'>
          <el-card class='box-card'>
            <div slot='header' class='clearfix'>
              <h2>{{ blogData.title }}</h2>
              <el-row :gutter='10'>
                <el-col :span='24'>
                  <i>简介：{{ blogData.description }}</i>
                </el-col>
              </el-row>
            </div>

            <article v-html='blogData.content' v-highlight />

            <el-row :gutter='10'>
              <el-col :span='12'>
                <el-tag
                  type='success'
                  v-for='(tag,index) in blogData.tags'
                  :key='index'
                  style='margin-right: 20px;'
                >
                  {{ tag }}
                </el-tag>
              </el-col>
              <el-col :span='4' :offset='8'>
                <p class='icons'>
                  <span class='iconfont good'> {{ blogData.likes }}</span>
                  <span class='iconfont view'> {{ blogData.views }}</span>
                  <span class='iconfont comments'> {{ blogData.comment.length }}</span>
                </p>
              </el-col>
            </el-row>
          </el-card>
        </el-col>
      </el-row>

      <div>
        <el-divider><i class='el-icon-chat-dot-square'></i></el-divider>
      </div>
      <CommentCard
        v-if='isShowComment && blogData.approved'
        :user-data='userDataProp'
        :blog-id='blogData.blogId'
        :title='blogData.title'
        :blog-author='authorProp'
        :comments='comments'
        :is-login='hasCommentPermission'
        @renderComments='renderComments'
      />
      <div v-else style='text-align:center;'>未审核的文章不能进行评论！</div>
    </el-card>
    <el-card v-else>
      <el-empty description='该文章不存在或者已被删除！' />
    </el-card>
    <el-dialog
      title='文章举报'
      :visible.sync='dialogVisible'
      width='30%'
    >
      <div>
        <h3>举报原因：</h3>
        <el-input type='textarea' placeholder='请输入举报原因' v-model='reason'></el-input>
      </div>
      <span slot='footer' class='dialog-footer'>
        <el-button @click='dialogVisible = false'>取 消</el-button>
        <el-button type='primary' @click='switchTipOff'>确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import BlogService from '@/service/blogs/BlogService'
import Filters from '@/tools/Filters'
import UserDetailService from '@/service/users/UserDetailService'
import TipOffService from '@/service/tip-off/TipOffService'
import CommentCard from '@/components/CommentCard'

// 用于设置代码高亮
import hljs from 'highlight.js'
// 高亮的样式
import 'highlight.js/styles/atom-one-dark.css'

export default {
  name: 'ArticleDetail',
  components: {
    CommentCard
  },
  filters: {
    timeFormat: Filters.timeFormat
  },
  directives: {
    // 自定义指令 代码高亮指令
    highlight: {
      bind(el) {
        setTimeout(() => {
          const codes = el.querySelectorAll('pre code')
          codes.forEach(code => {
            hljs.highlightBlock(code)
          })
        }, 10)
      }
    }
  },
  created() {
    // 初始化文章详情
    this.initArticleDetails()
  },
  data() {
    return {
      isSelf: false, // 用于判断该文章是否是当前登录用户所写
      isBlack: false,
      params: {
        blogId: ''
      },
      blogData: null,
      userData: JSON.parse(sessionStorage.getItem('userData')) || null,
      isLike: false,
      isAttention: false,
      reason: '',
      dialogVisible: false,
      isShowComment: false,
      comments: [],
      userDataProp: null,
      authorProp: null,
      hasCommentPermission: false
    }
  },

  methods: {
    goBack() {
      this.$router.go(-1)
    },

    // 初始化数据
    async initArticleDetails() {
      this.params.blogId = this.$route.params.id
      const res = await BlogService.getArticleDetailsById(this.params)

      if (res.data.status !== 200) {
        return this.blogData = null
      }

      this.blogData = res.data.data.blogData
      // 数据加载完毕 开启评论模块 否则子组件无法获取异步数据
      this.isShowComment = true
      // 对评论模块的 props 进行加工
      this.userDataProp = {
        userId: this.userData?.userId || '',
        name: this.userData?.userName || '',
        avatar: this.userData?.avatar || '',
        approved: this.userData?.approved || false,
        isAdmin: this.userData?.isAdmin || false,
        isAuthor: this.userData?.userId === this.blogData.author_id || false
      }

      this.authorProp = {
        author_id: this.blogData.author_id,
        name: this.blogData.author.userName,
        avatar: this.blogData.author.avatar
      }

      // 登录才有点赞、关注等操作权限
      if (this.userData) {
        // 判断当前文章是否属于当前登录用户
        this.isSelf = this.userData.userId === this.blogData.author_id
        // 更新对该文章的点赞状态
        this.isLike = this.userData.userDetails.likes.includes(this.blogData.blogId)
        // 更新对该作者的关注状态
        this.isAttention = this.userData.userDetails.attentions.includes(this.blogData.author_id)
        // 黑名单状态
        this.isBlack = this.userData.userDetails.blackList.includes(this.blogData.author_id)
        // 是否具有评论资格
        this.hasCommentPermission = true
      }

      // 渲染评论数据
      this.renderComments()
    },

    // 点赞功能
    async switchLike() {
      if (!this.userData?.approved) {
        return this.$message.error('未审核用户禁用点赞！')
      }

      if (this.isLike) {
        // 发起请求 取消点赞
        const res = await UserDetailService.unLikes(this.blogData.blogId)

        if (res.data.status === 200) {
          // 更新本地 sessionStorage 用户数据
          this.userData.userDetails.likes.splice(
            this.userData.userDetails.likes.indexOf(this.blogData.blogId),
            1
          )
          sessionStorage.setItem('userData', JSON.stringify(this.userData))
          this.blogData.likes--
          this.$message.success(res.data.message)
          this.isLike = false
        } else {
          this.$message.error(res.data.message)
        }

      } else {
        // 发起请求 点赞
        const res = await UserDetailService.setLikes({ blogId: this.blogData.blogId })

        if (res.data.status === 200) {
          // 更新本地 sessionStorage 用户数据
          this.userData.userDetails.likes.push(this.blogData.blogId)
          sessionStorage.setItem('userData', JSON.stringify(this.userData))
          this.blogData.likes++
          this.$message.success(res.data.message)
          this.isLike = true
        } else {
          this.$message.error(res.data.message)
        }
      }
    },

    // 关注功能
    async switchAttention() {
      if (!this.userData?.approved) {
        return this.$message.error('未审核用户禁用关注！')
      }

      if (this.isAttention) {
        // 发起请求 取关作者
        const res = await UserDetailService.unAttention(this.blogData.author_id)

        if (res.data.status === 200) {
          // 更新本地 sessionStorage 用户数据
          this.userData.userDetails.attentions.splice(
            this.userData.userDetails.attentions.indexOf(this.blogData.author_id),
            1
          )
          sessionStorage.setItem('userData', JSON.stringify(this.userData))
          this.$message.success(res.data.message)
          this.isAttention = false
        } else {
          this.$message.error(res.data.message)
        }

      } else {
        // 发起请求 关注作者
        const res = await UserDetailService.setAttention({ userId: this.blogData.author_id })

        if (res.data.status === 200) {
          // 更新本地 sessionStorage 用户数据
          this.userData.userDetails.attentions.push(this.blogData.author_id)
          sessionStorage.setItem('userData', JSON.stringify(this.userData))
          this.$message.success(res.data.message)
          this.isAttention = true
        } else {
          this.$message.error(res.data.message)
        }
      }
    },

    // 拉黑功能
    async switchBlack() {

      if (!this.userData?.approved) {
        return this.$message.error('未审核用户禁用拉黑！')
      }

      if (this.isBlack) {
        // 发起请求 移出黑名单
        const res = await UserDetailService.removeBlackList(this.blogData.author_id)

        if (res.data.status === 200) {
          // 更新本地 sessionStorage 用户数据
          this.userData.userDetails.attentions.splice(
            this.userData.userDetails.blackList.indexOf(this.blogData.author_id),
            1
          )
          sessionStorage.setItem('userData', JSON.stringify(this.userData))
          this.$message.success(res.data.message)
          this.isBlack = false

        } else {
          this.$message.error(res.data.message + '！ 请先登录！')
        }

      } else {
        // 发起请求 拉黑作者
        const res = await UserDetailService.addBlackList({ userId: this.blogData.author_id })
        if (res.data.status === 200) {
          // 更新本地 sessionStorage 用户数据
          this.userData.userDetails.blackList.push(this.blogData.author_id)
          sessionStorage.setItem('userData', JSON.stringify(this.userData))
          this.$message.success(res.data.message + ' 广场将不再展示该用户的博客！')
          this.isBlack = true
          setTimeout(() => {
            this.goBack()
          }, 2000)
        } else {
          this.$message.error(res.data.message)
        }
      }
    },

    // 举报功能
    async switchTipOff() {
      if (!this.userData?.approved) {
        return this.$message.error('未审核用户禁用举报！')
      }

      if (this.reason === '') {
        this.$message.error('请输入举报理由！')
        return false
      }
      // 发起请求 举报文章
      const { blogId, description, author_id, title, cover } = this.blogData
      const data = { blogId, description, author_id, title, cover, reason: this.reason }

      const res = await TipOffService.tipOffArticle(data)
      if (res.data.status === 200) {
        this.$message.success(res.data.message + '请等待管理员审核...')
      } else {
        this.$message.error(res.data.message)
      }
      this.reason = ''
      this.dialogVisible = false
    },

    // 删除文章
    async deleteBlog() {
      const res = await BlogService.deleteBlog(this.blogData.blogId)
      if (res.data.status !== 200) return this.$message.error(res.data.message)
      this.$message.success(res.data.message)
      setTimeout(() => this.goBack(), 1500)
    },

    showDialog() {
      this.dialogVisible = true
    },

    // 渲染评论数据
    async renderComments() {

      if (!this.blogData) return false
      // 请求评论数据
      const res = await BlogService.getArticleComments({ blogId: this.blogData.blogId })

      if (res.data.status !== 200) {
        return this.$message.error('获取评论失败！')
      }

      // 更新本地评论数据
      this.blogData.comment = res.data.data.comments
      // 对评论数据进行加工 传给评论子组件
      this.comments = this.blogData.comment || []

      // 使用 $set 把自定义属性设为响应式数据
      this.comments.forEach((comment) => {
        // 当前评论默认不在被回复的状态 用于每个子回复框的排异处理
        this.$set(comment, 'isReply', false)
        // 判断该评论是不是文章的作者 用于显示作者标识
        this.$set(comment, 'isAuthor', comment.author_id === this.blogData?.author_id)
        // 当前登录用户对该评论是否点赞
        this.$set(comment, 'isLike', comment.likes.includes(this.userData?.userId))

        // 遍历回复数组 给每一条回复都加上同样的标识
        comment.replies.forEach((reply) => {
          this.$set(reply, 'isReply', false)
          this.$set(reply, 'isAuthor', reply.author_id === this.blogData?.author_id)
          this.$set(reply, 'isLike', reply.likes.includes(this.userData?.userId))
        })
      })

    }
  }
}
</script>

<style scoped>
p, p > span {
  font-size: 20px;
}

p.icons {
  display: flex;
  justify-content: end;
}

p.icons span {
  display: inline-block;
  margin-left: 10px;
  color: gray;
}

[class*=" el-icon-"], [class^=el-icon-] {
  font-size: 30px;
}

div.el-divider, div.el-divider--horizontal {
  height: 4px !important;
}

.el-row {
  display: flex;
  align-items: center;
}

strong.admin {
  margin-left: 10px;
  padding: 2px;
  font-size: 14px;
  color: #e3487b;
  border: 1px solid #e3487b;
  border-radius: 4px;
}

>>> article pre code {
  font-size: 20px;
  border-radius: 10px;
}
</style>
